import Unit from "./Unit";
export enum EffectMethod{
    OverWrite,
    Add,
    Reduce
}
export class Effect {
    public data: any;
    public method:number;
    public totalTime?: number;
}
export abstract class Buff {
    public targatUnit: Unit = null;
    public fromUnit: Unit = null;
    public effect: Effect = null;

    public abstract update(dt): void;
}
export class FlashDamageBuff extends Buff {
    public update(dt?) {
            if (this.fromUnit.isDeath()) {
                return;
            }
            this.targatUnit.buffManager.applyEffect(this.effect);
            this.targatUnit.buffManager.removeBuff(this);
    }
}
export class ContinueDamageBuff extends Buff {
    //isStart = false;
    public constructor(effect) {
        super();
        this.effect = effect;
        this.currentTime = 0;
        this.count = 0;
        this.totalTime = this.effect.totalTime;

    }
    private currentTime = 0;
    private totalTime = 3;
    private count = 0;
    public update(dt?) {
        if (this.fromUnit.isDeath()) {
            return;
        }
        this.currentTime += dt;
       
        if (this.currentTime > this.count) {
            if (this.targatUnit.buffManager) {


                this.targatUnit.buffManager.applyEffect(this.effect);
                ++this.count;
            }

        }
        if (this.count >= this.totalTime && this.targatUnit.buffManager) {
            this.targatUnit.buffManager.removeBuff(this);
        }
    }
}
export class BuffManager {
    
    public unit: Unit;
    public buffs: Set<Buff>;

    public constructor(unit: Unit) {
        this.unit = unit;
        unit.buffManager = this;
        this.buffs = new Set<Buff>();
    }

    public removeBuff(buff: Buff) {
        return this.buffs.delete(buff);
    }
    public addBuff(buff: Buff) {
        this.buffs.add(buff);
    }
    public update(dt?) {
        this.buffs.forEach((buff: Buff) => {

            buff.update(dt);
        });
    }
    public clear() {
        this.buffs.clear();
    }
    public applyEffect(effect:Effect) {
        if (effect) {
            for (const key in effect.data) {
                const element = effect.data[key];
                this.unit.resetProperty(key, element,effect.method);
            }
        }

    }
}